package zdm.core;

import zdm.core.aop.ZdmProceedingJoinPoint;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

/**
 * AOP代理的调用处理器
 *
 * @author zdm
 * @date 2025/08/27
 */
public class AopInvocationHandler implements InvocationHandler {
    // 原始的被代理对象
    private final Object target;
    // 切面类实例
    private final Object aspect;
    // 前置通知方法
    private final Method adviceMethod;

    private final String adviceType;   // 通知类型 ("before" 或 "around")

    public AopInvocationHandler(Object target, Object aspect, Method adviceMethod, String adviceType) {
        this.target = target;
        this.aspect = aspect;
        this.adviceMethod = adviceMethod;
        this.adviceType = adviceType;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        // 根据通知类型，执行不同的逻辑
        switch (adviceType) {
            case "around":
                // 对于Around通知
                // 1. 创建一个 "通行令牌" (ProceedingJoinPoint)
                ZdmProceedingJoinPoint pjp = new ZdmProceedingJoinPoint(target, method, args);
                // 2. 将令牌交给 "门卫" (Around通知方法)，让它全权处理
                return adviceMethod.invoke(aspect, pjp); // 注意，这里把pjp作为参数传了进去
            case "before":
                // 对于Before通知，逻辑不变
                adviceMethod.invoke(aspect);
                return method.invoke(target, args);
            default:
                // 如果没有匹配的通知类型，直接执行原始方法
                return method.invoke(target, args);
        }
    }
}